
#include <iostream>   
#include <fstream>
#include <map>

#include <unistd.h>
#include <sys/stat.h>

#include "rectype.h"
#include "recbase.h"
#include "util.h"
#include "stdfreader.h"
#include "stdfrecscont.h"
#include "stdfconfig.h"


#include "ptr.h"



using namespace std;
using namespace opsrc::stdf;


StdfReader::StdfReader():file(NULL),stdfrecs(NULL) {
    of = NULL;
}

StdfReader::~StdfReader() {
    this->closeStdfFile();
}

string StdfReader::welcomeMessage() {
    string msg = "STDF reader v20110504";
    return msg;
}




void StdfReader::openStdfFile(string filename) {
#if _DEBUG
    //	cout << "call openStdfFile():" << endl;
#endif
    cout << "Reading file " << filename << endl;
    if (this->file==NULL)
        this->file = new ifstream(filename.c_str(), std::ios::binary|std::ios::in);
    else
        this->file->open(filename.c_str(), std::ios::binary|std::ios::in);

    file->clear();

}

void StdfReader::closeStdfFile() {
    if (file!=NULL) 
    {
    	if (file->is_open())
    	    file->close();

    	delete file;
    	file = NULL;	
    }

}

void StdfReader::setOutFormat(OutFormat*& out) {
    this->of = out;
}

void StdfReader::initialize() {   
    // read in STDF records
    try {

        //Change current directory to store all data to respective folder
        if( chdir( StdfConfig::instance()->getSrcDir().c_str() ) == -1) {
            std::cerr<<"\nSRC:"<<StdfConfig::instance()->getSrcDir().c_str();
            std::cerr<<"\nInvalid Source directory. Check StdfParser.cfg file!";
        }

        string str;

        if(StdfConfig::instance()->getSrcDir() == "."){
            str = StdfConfig::instance()->getFilename();
        }
        else {
            str = StdfConfig::instance()->getSrcDir() + StdfConfig::instance()->getFilename();
        }
        cout << "file is: " << str << endl;

        //openStdfFile(StdfConfig::instance()->getSrcDir()+"/"+str);
        openStdfFile(str);

        //Change current directory to store all data to respective folder
        if( chdir( StdfConfig::instance()->getDestDir().c_str() ) == -1) {
            std::cerr<<"\nDEST:"<<StdfConfig::instance()->getDestDir().c_str();
            std::cerr<<"\nInvalid destination directory. Check StdfParser.cfg file!";
        }

        of->out("file load - ok\n\0");

        //Create a working directory name base on the filename
        struct stat st;
        str = StdfConfig::instance()->getFilename();
        cout<<"\nStore Directory:" << str.c_str() <<endl;

        int rpos = str.find_last_of("/\\");
        int pos = str.find(".stdf");
        if(rpos<0) rpos = 0;
        str = StdfConfig::instance()->getDestDir().c_str() + str.substr(rpos, pos-rpos);
        cout<<"\nStore Directory:" << str.c_str() <<endl;

        if(stat(str.c_str(),&st) == 0)
        {
            std::cout<<str.substr(0, pos) << " is present\n";
        }
        else mkdir(str.c_str(), 0777);
        //chdir( str.substr(0, pos).c_str() );
        outputFolder = str;
        chdir(str.c_str());
        
        // get total file length
        file->seekg(0,std::ios::beg);
        file->seekg(0,std::ios::end);
        long filesize = file->tellg();
        
        file->seekg(0,std::ios::beg); // return to beginning of file
        of->out("filesize = ");
        of->out(filesize);
        of->out("\n");
    }
    catch (...) {
#if _DEBUG
        //		cout << "An error has occurred while parsing STDF file" << endl;
#endif
        if (file !=NULL && file->is_open() )
            closeStdfFile();
    }
    return;

}


void StdfReader::read() {

    try {

        if( file == 0){
            printf("File handler is not declared. Check configuration!");
            return;
        }

        file->seekg(0,std::ios::end);
        long filesize = file->tellg();
        file->seekg(0,std::ios::beg); // return to beginning of file

        // go to 5th byte from beginning of file
        // establish type of endian
        file->seekg(4, std::ios::beg);
	
        if (stdfrecs == NULL ) {
            stdfrecs = new StdfRecsCont();
            stdfrecs->setOutFormat(of);
        }

        stdfrecs->setEndian(Util::stdfCpuTypeEndian(file->get()));

        // reset filebyteposition pointer
        file->seekg(0, std::ios::beg);
        while ( !(file->eof() || file->fail())  ) {

            if (  file->tellg() < filesize ) {
                if ( !stdfrecs->createRec(file, true) )  break;
            }
            else {
                break;
            }

        }
        cout << "Parsing completed"  << endl;
        
        closeStdfFile();
        stdfrecs->saveRecords();
        
        /* Create complete.txt file */
        chdir(outputFolder.c_str());
        std::ofstream* cfile = new std::ofstream;
        if( !cfile->is_open() )
        {
            cfile->open("complete.txt");
        }

        cfile->close();
        delete cfile;
    }
    catch (...) {
        cerr << "An error has occurred while parsing STDF file" << endl;
        if (file !=NULL && file->is_open() )
            closeStdfFile();
    }
    return;
}

